package com.gksc.jcef;

import com.gksc.jcef.constant.BusinessConstant;
import com.gksc.jcef.data.TabBrowser;
import com.gksc.jcef.handle.TabCloseHandler;
import com.gksc.jcef.handle.TabOpenHandler;
import com.gksc.jcef.util.Tool;
import org.cef.CefApp;
import org.cef.CefApp.CefAppState;
import org.cef.CefClient;
import org.cef.CefSettings;
import org.cef.browser.CefBrowser;
import org.cef.browser.CefFrame;
import org.cef.handler.CefAppHandlerAdapter;
import org.cef.handler.CefDisplayHandlerAdapter;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.net.URL;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @className: ChromeTabFrame
 * @description: 内嵌Google浏览器访问tab页面-入口
 * @author: Liao.yx
 * @email: 1229053515@qq.com
 * @create: 2021年05月28日 10时24分
 * @copyRight: 2020 liaoyongxiang All rights reserved.
 **/
public class ChromeTabFrame extends JFrame {
    /**
     * cef-app应用
     */
    private CefApp app;
    /**
     * cef-client对象
     */
    private CefClient client;
    /**
     * tabbedPane对象
     */
    private JTabbedPane tabbedPane;
    /**
     * Tab索引号
     */
    public static AtomicInteger tabIndex = new AtomicInteger(0);
    /**
     * TabBrowser对象列表
     */
    private List<TabBrowser> tabList = new LinkedList<>();

    public ChromeTabFrame(String appName, String icon, int width, int height, int posX, int posY, String startURL, String title, String logPath, boolean useOSR,
                          boolean isTransparent, boolean isShowAddr, boolean isCloseExit, boolean isChangeSize) {
        if (width <= 0 && height <= 0) {
            width = BusinessConstant.width;
            height = BusinessConstant.height;
        }
        if (posX <= 0 || posY <= 0) {
            Toolkit toolkit = Toolkit.getDefaultToolkit();
            posX = (int) (toolkit.getScreenSize().getWidth() - width) / 2;
            posY = (int) (toolkit.getScreenSize().getHeight() - height) / 2;
        }
        this.setTitle(Tool.isEmpty(appName) ? "java集成cef测试程序" : appName);
        URL resource = this.getClass().getClassLoader().getResource(Tool.isEmpty(appName) ? "logo.jpg" : icon);
        ImageIcon image = new ImageIcon(resource);
        this.setIconImage(image.getImage());
        this.setAlwaysOnTop(true);//总在最前面
        this.setResizable(isChangeSize);
        this.setUndecorated(false);//去处边框
        this.setDefaultCloseOperation(EXIT_ON_CLOSE);
        CefApp.addAppHandler(new CefAppHandlerAdapter(null) {
            @Override
            public void stateHasChanged(CefAppState state) {
                if (state == CefAppState.TERMINATED) {
                    System.exit(0);
                }
            }
        });
        CefSettings settings = new CefSettings();
        settings.windowless_rendering_enabled = useOSR;
        settings.log_file = Tool.isEmpty(logPath) ? "c:\\cef.log" : logPath;
        app = CefApp.getInstance(settings);
        tabbedPane = new JTabbedPane(JTabbedPane.TOP, JTabbedPane.SCROLL_TAB_LAYOUT);
        client = app.createClient();
        client.addDisplayHandler(new TabOpenHandler(title, this));
        createBrowser(title, startURL, useOSR, isTransparent, isShowAddr);
        this.getContentPane().add(tabbedPane);
        pack();
        this.setSize(width, height);
        this.setLocation(posX, posY);
        this.setVisible(true);

        addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                closeAllTabs();
                if (isCloseExit) {
                    System.exit(1);
                } else {
                    setVisible(false);
                }
            }
        });
    }

    /**
     * 创建浏览器
     * @param title
     * @param startURL
     * @param useOSR
     * @param isTransparent
     * @param isShowAddr
     * @return
     */
    public int createBrowser(String title, String startURL, boolean useOSR, boolean isTransparent, boolean isShowAddr) {
        CefBrowser browser = client.createBrowser(startURL, useOSR, isTransparent);
        Component browserUI = browser.getUIComponent();
        JTextField addressUI = new JTextField(startURL, 100);
        addressUI.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                browser.loadURL(startURL);
            }
        });
        if(isShowAddr){
            JFrame container = new JFrame();
            container.getContentPane().add(addressUI, BorderLayout.NORTH);
            container.getContentPane().add(browserUI);
            tabbedPane.addTab(title, container.getContentPane());
        }else {
            tabbedPane.addTab(title, browserUI);
        }

        int lastIndex = tabbedPane.getTabCount() - 1;
        tabIndex.getAndIncrement();
        JPanel jPanel = new JPanel();
        JLabel titleUI = new JLabel(title);
        JLabel closeUI = new JLabel("X");
        jPanel.setOpaque(false);
        titleUI.setHorizontalAlignment(JLabel.LEFT);
        closeUI.setHorizontalAlignment(JLabel.RIGHT);
        jPanel.add(titleUI);
        jPanel.add(closeUI);
        closeUI.addMouseListener(new TabCloseHandler(lastIndex, this));
        tabbedPane.setTabComponentAt(lastIndex, jPanel);
        TabBrowser tabBrowser = new TabBrowser(tabIndex.get(), browser, titleUI, addressUI, true);
        tabList.add(tabBrowser);
        tabbedPane.setSelectedIndex(lastIndex);

        return lastIndex;
    }

    /**
     * 关闭所有浏览器
     */
    public void closeAllTabs() {
        for (int i = tabList.size() - 1; i >= 0; i--) {
            TabBrowser tab = tabList.get(i);
            tab.getBrowser().close(true);
            tabbedPane.removeTabAt(i);
            tabList.remove(tab);
            System.out.println("移除索引为" + i + "的tab页");
        }
        System.exit(1);
    }

    /**
     * 修改标题
     *
     * @param title
     * @param address
     * @param browser
     */
    public void updateTabTitle(String title, String address, CefBrowser browser) {
        if (title != null && !"".equals(title)) {
            if (title.length() > 12) title = title.substring(0, 12) + "...";
            for (TabBrowser tb : tabList) {
                if (tb.getBrowser() == browser) {
                    tb.getTitle().setText(title);
                    tb.getAddress().setText(address);
                    tb.setBrowserFocus(true);
                    break;
                }
            }
        }
    }

    /**
     * 移除tab
     *
     * @param index 索引号
     */
    public void removeTab(int index) {
        if (tabList.size() > 1) {
            for (int i = 0; i < tabList.size(); i++) {
                TabBrowser tb = tabList.get(i);
                if (tb.getIndex() == index) {
                    tb.getBrowser().close(true);
                    tabbedPane.removeTabAt(i);
                    tabList.remove(i);
                    break;
                }
            }
        } else {
            closeAllTabs();
        }
    }

    public static void main(String[] args) {
        ChromeTabFrame main = new ChromeTabFrame(null, null, 0, 0, 0, 0, "https://gitee.com/", "测试Tab页面", null, false, false, false, true, true);
        main.createBrowser("测试Tab2页面","http://www.baidu.com/",false,false,false);

    }
}
